var Cheetah = window.Cheetah || {};

Cheetah.AUtils = new function () {
    let au = this;

    // 可以信息加密，再解密
    au.parseProtocol = function (data, callback) {
        // 解析协议 do something
        data = JSON.parse(data);

        callback(data);
    }

    au.parseMessage = function (data, websocketCallback) {
        switch(data.command){
            case Cheetah.Command("LOGIN_RESPONSE") :
                if(data.statusCode == 100)
                    websocketCallback({status: "success", message: "websocket登录成功"}, "onLoginMessage");
                break;
            case Cheetah.Command("MESSAGE_RESPONSE") :
                if(data.statusCode == 102)
                    // 消息应答，不处理
                break;
            case Cheetah.Command("MESSAGE_REQUEST") :
                if(data.statusCode == 103)
                    websocketCallback({data: {fromId: data.fromId, message: data.message}}, "onSingleMessage");
                break;
            case Cheetah.Command("GROUP_MESSAGE_RESPONSE") :
                if(data.statusCode == 104)
                    // 消息应答，不处理
                break;
            case Cheetah.Command("GROUP_MESSAGE_REQUEST") :
                if(data.statusCode == 105)
                    websocketCallback({data: {fromId: data.fromId, message: data.message}}, "onGroupMessage");
                break;
            case Cheetah.Command("HEART_BEAT_RESPONSE") :
                if(data.statusCode == 201)
                    websocketCallback({data: {message: data.message}}, "onIdleStateMessage");
                break;
        }
    }
}();

Cheetah.Command = (function () {
    let command = {
        HEART_BEAT_REQUEST: 30,
        HEART_BEAT_RESPONSE: 31,
        LOGIN_REQUEST: 1,
        LOGIN_RESPONSE: 2,
        MESSAGE_REQUEST: 3,
        MESSAGE_RESPONSE: 4,
        GROUP_MESSAGE_REQUEST: 5,
        GROUP_MESSAGE_RESPONSE: 6,
    }
    return function (key) {
        return command[key.toUpperCase()]
    }
})();

Cheetah.CheetahConfig = function(config) {
    config = config || {};
    this.msgServerUrl = config["msgServerUrl"] || "";
    this.msgServerWebsocketPort = config["msgServerWebsocketPort"] || 0;

    this.idleStateRead = config["idleStateRead"] || 5000;
    this.idleStateWrite = config["idleStateWrite"] || 5000;
};

Cheetah.CheetahUserInfo = function(userInfo) {
    userInfo = userInfo || {};
    this.appId = userInfo["appId"] || "";
    this.userId = userInfo["userId"] || "";
};

/**
 * 标志位记录，是否需要发送心跳包
 *  根据readTime和writeTime
 *
 * @param readForTime
 * @param writeForTime
 * @constructor
 */
Cheetah.CheetahIdleState = function(readForTime, writeForTime) {
    let cheetahIdleState = this;

    this.readForTime = readForTime;
    this.writeForTime = writeForTime;

    this.readTime = getDate();
    this.writeTime = getDate();

    cheetahIdleState.setReadTime = function () {
        this.readTime = getDate();
    }

    cheetahIdleState.setWriteTime = function () {
        this.writeTime = getDate();
    }

    cheetahIdleState.getReadIDLE = function(){
        let currentTime = getDate();
        if(currentTime - this.readTime > this.readForTime){
            return true;
        }
        return false;
    }

    cheetahIdleState.getWriteIDLE = function(){
        let currentTime = getDate();
        if(currentTime - this.writeTime > this.writeForTime){
            return true;
        }
        return false;
    }

    function getDate(){
        return new Date().getTime();
    }
};

Cheetah.CheetahSDK = function() {
    let cheetahSDK = this;
    let websocketClient = null;
    let userCallback = null;

    cheetahSDK.cheetahConfig = new Cheetah.CheetahConfig();
    cheetahSDK.cheetahUserInfo = new Cheetah.CheetahUserInfo();
    cheetahSDK.CheetahIdleState = null;

    let websocketCallback = function(data, status){
        switch (status) {
            case"connect success":
                cheetahSDK.startAuth();
                userCallback(data, status);
                break;
            case"connect failed":
            case"connect closed":
                websocketClient = null;
                userCallback(data, status);
                break;
            case"onmessage":
                cheetahSDK.CheetahIdleState.setReadTime();
                Cheetah.AUtils.parseProtocol(data, function (data) {
                    Cheetah.AUtils.parseMessage(data, websocketCallback);
                });
                break;
            case"onLoginMessage":
                if ("success" == data.status)
                    if(null != websocketClient){
                        let heartBeat = {};
                        heartBeat.command = Cheetah.Command("HEART_BEAT_REQUEST");
                        websocketClient.startHeartBeat(JSON.stringify(heartBeat), 1000);
                    }
                    userCallback(data, status);
                break;
            case"onSingleMessage":
                userCallback(data, status);
                break;
            case"onIdleStateMessage":
                userCallback(data, status);
                break;
        }
    }
    
    cheetahSDK.setUserInfo = function (appId, userId) {
        cheetahSDK.cheetahUserInfo.appId = appId;
        cheetahSDK.cheetahUserInfo.userId = userId;
    }

    cheetahSDK.setMsgServerInfo = function (ip, port) {
        cheetahSDK.cheetahConfig.msgServerUrl = ip;
        cheetahSDK.cheetahConfig.msgServerWebsocketPort = port;
    }

    cheetahSDK.setIdleStateTime = function (idleStateRead, idleStateWrite) {
        cheetahSDK.cheetahConfig.idleStateRead = idleStateRead;
        cheetahSDK.cheetahConfig.idleStateWrite = idleStateWrite;
        cheetahSDK.CheetahIdleState = new Cheetah.CheetahIdleState(cheetahSDK.cheetahConfig.idleStateRead, cheetahSDK.cheetahConfig.idleStateWrite);
    }

    cheetahSDK.login = function (appId, userId, callback) {
        userCallback = callback;

        cheetahSDK.cheetahUserInfo.appId = appId;
        cheetahSDK.cheetahUserInfo.userId = userId;
        return function (callback) {
            if ("WebSocket" in window) {
                websocketClient = new Cheetah.WebsocketClient(callback, cheetahSDK.CheetahIdleState);
                websocketClient.connect("ws://" + cheetahSDK.cheetahConfig.msgServerUrl + ":" + cheetahSDK.cheetahConfig.msgServerWebsocketPort + "/cheetah");
            } else {

            }
        }(websocketCallback);
    }

    cheetahSDK.startAuth = function () {
        let data = {
            appId: cheetahSDK.cheetahUserInfo.appId,
            userId: cheetahSDK.cheetahUserInfo.userId,
            command: Cheetah.Command("LOGIN_REQUEST")
        }
        cheetahSDK.send(JSON.stringify(data));
    }

    cheetahSDK.sendSingleMessage = function (data) {
        data.userId = cheetahSDK.cheetahUserInfo.userId;
        data.appId = cheetahSDK.cheetahUserInfo.appId;
        data.command = Cheetah.Command("MESSAGE_REQUEST");
        cheetahSDK.send(JSON.stringify(data));
    }

    cheetahSDK.send = function (data) {
        cheetahSDK.CheetahIdleState.setWriteTime();
        null != websocketClient && websocketClient.send(data);
    }
};

Cheetah.WebsocketClient = function (websocketCallback, cheetahIdleState) {
    let websocketClient = this;
    let websocket = null;
    let interval = null;

    websocketClient.connect = function (url) {
        websocket = new WebSocket(url + "?command=0");

        websocket.onerror = function (event) {
            websocketCallback({msg: "websocket连接发生错误", data: event.data}, "connect failed");
        }
        websocket.onopen = function (event) {
            websocketCallback({msg: "websocket连接成功"}, "connect success")
        }
        websocket.onmessage = function (event) {
            websocketCallback(event.data, "onmessage")
        }
        websocket.onclose = function (event) {
            websocketClient.stopHeartBeat();
            websocketCallback({msg: "websocket连接关闭", data: event}, "connect closed");
            websocket = null;
            // 此处可以重连
        }
    }

    websocketClient.startHeartBeat = function (message, time) {
        if(null != websocket && 1 == websocket.readyState){
            interval = setInterval(function () {
                if(null != websocket && 1 == websocket.readyState){
                    if(cheetahIdleState.getReadIDLE() && cheetahIdleState.getWriteIDLE()){
                        cheetahIdleState.setReadTime();
                        cheetahIdleState.setWriteTime();
                        console.log("发送心跳包");
                        websocket.send(message);
                    }
                }
            }, time);
        }
    }

    websocketClient.stopHeartBeat = function () {
        clearInterval(interval);
    }

    websocketClient.send = function (message) {
        websocket.send(message);
    }

    websocketClient.close = function () {
        null != websocket && websocket.close();
    }

    websocketClient.readyState = function () {
        return null != websocket ? websocket.readyState : -1;
    }

    websocketClient;
}

